home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
- * ispCODE5C.c *
- * ispCODE for ispLSI 2000V Devices *
- * Lattice Semiconductor Corp. Copyright 1996,1997. *
- * *
- * ISP(tm) daisy chain turbo programming is supported by ispCODE. *
- * *
- * The function of ispCODE is to step the IEEE 1149.1 TAP state machine *
- * in the ispLSI devices for programming and verification. The input file *
- * for ispCODE is ispSTREAM file. *
- * *
- * The ispSTREAM file is created by the command line program dld2isp.exe *
- * and the ISP Daisy Chain Download program version 1.3 or higher. *
- * *
- * This version of ispCODE is the much simplified version of ispCODE V3.xx *
- * by removing the PES checking, the post BULK ERASE verification and the *
- * simultaneous shifting data in and out. The programming time is thus a bit *
- * longer than V3.xx due to the additional time needed to shift data in and *
- * out separately. It is a very little price to pay for a 50% reduction in *
- * code size which is especially critical for embedded controller programming*
- * where resources is extremely limited. *
- * *
- * The file size of Super FULL ispSTREAM is about 30% less than the FULL *
- * ispSTREAM. The saving comes from replacing long chain of 0xFFs with *
- * the number of consecutive 0xFF bytes. For example: *
- * 0xFF,0xFF,0xFF,0xC3 is reduced to 0xFF,0x03,0xC3 *
- * *
- * The Super FULL ispSTREAM file is created by the command line program *
- * dld2isp.exe v4.03 with the option sf selected. For example: type *
- * dld2isp design.dld sf *
- * *
- * All ispLSI 2000LV family of devices support the IEEE 1149.1 32-bit *
- * USERCODE. The USERCODE data must be appended into the JEDEC file if it *
- * is to be programmed into the device. The UES editor on the ISP Daisy *
- * Chain Download should be used to add or modify the USERCODE data. *
- * It is important to note that USERCODE is only 32 bits long. The extra *
- * bits will still be written into the JEDEC file but will be discarded *
- * during USERCODE programming if more than 32 bits of data is entered *
- * on the UES editor. *
- * *
- * Programming and verification always include all Array Cells and the *
- * entire USERCODE. The USERCODE is programmed to be FFFFFFFF in hex by *
- * default. *
- * *
- * The procedure of reading USERCODE is as follows: *
- * 1. Raise TMS to VIH and pulse TCK 6 times to step to Test-Logic Reset *
- * state. *
- * 2. TMS to VIL, pulse TCK 1 time. *
- * 3. TMS to VIH, pulse TCK 2 times. *
- * 4. TMS to VIL, pulse TCK 2 times to step to Shift-IR state. *
- * 5. TMS stay at VIL, shift in the VERIFY_USERCODE instruction 10111 *
- * into the IR via TDI and pulse TCK. The instruction is shifted in *
- * from right to left, i.e. 1, 1, 1, 0 and 1. Repeat the instruction *
- * if there is more than one ispLSI device in the chain. Raise TMS to *
- * VIH while shifting in the last bit. *
- * 6. Keep TMS at VIH, pulse TCK 2 times to step to Select-DR-Scan state. *
- * 7. TMS to VIL, pulse TCK 2 times to step to Shift-DR state. *
- * 8. Keep TMS at VIL, pulse TCK 32 times to shift out the 32 bits *
- * USERCODE on TDO. Pulse TCK 32 times more if more than one device *
- * in the chain. Raise TMS to VIH while shifting out the last bit. *
- * *
- * 9. Keep TMS at VIH and pulse TCK 6 times to go back to Test-Logic *
- * Reset state to end the procedure. *
- * *
- * Revision history: *
- * 4.0 Howard Tang 05/16/96 Convert from V3.xx to support ISP(tm) *
- * programming using the IEEE 1149.1 TAP *
- * for ispLSI 2000LV family of devices. *
- * ispLSI 3000 family of devices are also *
- * supported if they are on bscan *
- * daisy chain configuration. *
- * Simplify the code of ispstream_pump *
- * for easier reading and use. *
- * 5C.000 Howard Tang 11/01/96 Simplify codes. *
- * 5C.001 Howard Tang 01/17/97 Extend support to GDX devices. *
- * *
- *****************************************************************************/
- #include <stdio.h>
- #include <dos.h>
- #include <stdlib.h>
- #include <string.h>
- #include "lattice.h"
- #include "istream.hex"
-
- /*Global variables */
- static short int bit=0; /*the current bit read from ispSTREAM*/
- static unsigned char curch; /*the current data from ispSTREAM*/
- unsigned char *fp; /*the pointer to the ispSTREAM*/
- static short int inputport=inport1, /*port address for the input port*/
- outputport=outport1; /*port address for the output port*/
- static short int isp_pins=NUL; /*3.02 holds the value of parallel port*/
- /* intialized to drive all pins to LOW*/
- static char state; /*4.0 Keep track of the state of the TAP
- state machine.*/
-
- /*prototypes*/
- void pulse_width(unsigned short int milliseconds);
- void execute(void);
- void move_to_id_state(void);
- short int ispstream_pump(short int operation, short int *end);
- void error_handler(short int rcode, char *message);
- unsigned char GetByte(void);
- void ReadispSTREAMHeader(short int *ChainLength, short int *ErasePulse,
- short int *ProgramPulse, short int *RowLength,
- unsigned short int *DataSize,
- unsigned short int *IDStreamLength);
- char ispRead(unsigned short int DataSize, unsigned char *OutData);
- void ReadispSTREAMDataSize(unsigned short int *DataSize);
- void ReadispSTREAMData(unsigned short int *DataSize, unsigned char *InData,
- char SF);
- char ispInstruction(char SF,char Send);
- void ispData( unsigned char *InData, unsigned short int DataSize);
- void program_enable(short int chips);
- void device_enable(short int chips);
-
- /***************************************************************************
- Function: isp_setpin(byte pins, byte value)
-
- Purpose:
- To apply the specified value to the pins indicated. This routine will
- likely be modified for specific systems. As an example, this code
- is for the PC, as described below.
-
- This routine uses the IBM-PC standard Parallel port, along with the
- schematic shown in Lattice documentation, to apply the signals to the
- programming loop.
-
- PC Parallel port pin Signal name
- -------------------- -----------
- 2 out_SDI
- 3 out_SCLK
- 4 out_MODE
- 5 out_ISP
- 6 out_RESET
- 7 DO5
- 8 out_SENSE_CABLE_OUT
- 9 DO7
- 10 in_SDO
- 12 in_CABLE_SENSE_IN
- 15 in_VCC_OK
- 20 GND
-
- Parameters:
- - pins, which is actually a set of bit flags (defined in lattice.h)
- that correspond to the bits of the data port. Each of the I/O port
- bits that drives an isp programming pin is assigned a flag
- (through a #define) corresponding to the signal it drives. To
- change the value of more than one pin at once, the flags are added
- together, much like file access flags are.
-
- The bit flags are only set if the pin is to be changed. Bits that
- do not have their flags set do not have their levels changed. The
- state of the port is always manintained in the static global
- variable isp_pins, so that each pin can be addressed individually
- without disturbing the others.
-
- - value, which is either HIGH (0x01 ) or LOW (0x00 ). Only these two
- values are valid. Any non-zero number sets the pin(s) high.
-
- Returns: nothing.
-
-
- **************************************************************************/
- void isp_setpin(unsigned char pins, unsigned char value)
- {
- /* isp_pins is a Global value that keeps track of the current state
- of the pins */
-
- if( value ) /* set flagged pins HIGH */
- isp_pins = pins | isp_pins;
- else /* set flagged pins LOW */
- isp_pins = ~pins & isp_pins;
-
- /* value is put on Parallel port pins */
- outp(outputport, isp_pins);
-
- } /* isp_setpin() */
-
-
- /***************************************************************************
- Function: isp_SDO()
-
- Purpose:
- To get the value of the SDO pin from the input port.
-
- This routine is specific to the PC parallel port setup, but can easily
- be changed to address each user's hardware.
-
- Parameters: none
-
- Returns: The value of SDO, as a byte, with a value of either 0 or 1.
-
- Notes:
- - This routine uses the I/O port addresses contained in the global
- variable inputport, declared in the lattice.h file.
-
- ****************************************************************************/
- unsigned char isp_SDO(void)
- {
- /* MUST return either 0x00 or 0x01 */
- return( (unsigned char) ((inp(inputport) & in_SDO ) ? HIGH : LOW) );
-
- } /* isp_SDO() */
-
- /*************************************************************
- * *
- * PULSE_WIDTH *
- * This procedure produce accurate timing only on straight PC *
- * DOS. The timing is not guarantee if use on Windows DOS. *
- * The delay() function is available only from BORLAND. *
- * *
- * Users must devise their own timing procedures to ensure *
- * the specified minimum delay is observed when using *
- * different platform. *
- *************************************************************/
-
-
- void pulse_width(unsigned short int milliseconds)
- {
- delay(milliseconds);
- }
-
-
-
- /*************************************************************
- * *
- * GETBYTE *
- * This procedure reads a byte from the ispSTREAM. *
- *************************************************************/
- unsigned char GetByte()
- {
- return (*fp++);
- }
-
-
- /*************************************************************
- * *
- * SCLOCK *
- * This procedure apply a clock to TCK. *
- *************************************************************/
- void sclock(void)
- {
- isp_setpin(out_SCLK,HIGH);
- isp_setpin(out_SCLK,LOW);
- }
-
- /*************************************************************
- * *
- * SHIFT/EXECUTE *
- * This procedure walk all devices in the daisy chain from a *
- * given state to the next desirable state. *
- * *
- *If at Idle state when enter then move to Shift-IR state. *
- *If at Shift-IR state when enter then move to Shift-DR state.*
- *If at Shift-DR state when enter then move to Shift-IR state.*
- *If at Shift-IR state and state is set to time_state when *
- *enter then move to Idle state. *
- *************************************************************/
- void execute()
- {
- short int i,count;
- if (state==time_state)
- {count = 1; /*move from shift-IR to Idle state to start timing*/
- state = idle_state;
- }
- else if (state==shift_state)
- {count = 2; /*move from shift-IR to shift-DR*/
- state = execute_state;
- }
- else if (state==idle_state)
- {count = 2; /*move from Idle to shift-IR state*/
- state = shift_state;
- }
- else if (state==execute_state)
- {count = 3; /*move from shift-DR to shift-IR*/
- state = shift_state;
- }
- else count = 0;
- isp_setpin(out_SCLK,LOW);
- isp_setpin(out_MODE,LOW);
- isp_setpin(out_SDI,LOW);
- for (i=0; i<count; i++)
- {
- isp_setpin(out_MODE,HIGH);
- sclock();
- }
- isp_setpin(out_MODE,LOW);
- sclock();
- if (count > 1) sclock();
- /* at Shift-DR or Shift-IR state*/
-
- }
-
-
- /*************************************************************
- * *
- * MOVE TO ID STATE *
- * This procedure walk all devices in the daisy chain to the *
- * Test-Logic-Reset state then Run-Test/Idle state. *
- * *
- *************************************************************/
-
- void move_to_id_state()
- {
- int i;
- isp_setpin(out_SCLK,LOW);
- isp_setpin(out_MODE+out_SDI,LOW);
- pulse_width(2);
- isp_setpin(out_MODE,HIGH);
- pulse_width(2);
- isp_setpin(out_SCLK,HIGH);
- pulse_width(2);
- isp_setpin(out_SCLK,LOW);
- for (i=0; i<6; i++) sclock();
- isp_setpin(out_MODE,LOW);
- pulse_width(2);
- sclock(); /*device is in Idle state*/
- state = idle_state;
- }
-
- /*************************************************************
- * *
- * PROGRAM ENABLE *
- * perform the 3 read id instruction to get devices into *
- * programming mode. *
- *************************************************************/
-
- void program_enable(short int chips)
- {
- short int i,j,loops;
-
- for (loops=0; loops<3; loops++)
- {
- for (i=0; i<chips+1; i++)
- for (j=0; j<5; j++) /*send the instruction into TDI*/
- {if ((i==chips)&&(j==4)) isp_setpin(out_MODE,HIGH); /*last bit*/
- isp_setpin(out_SDI,(PROGRAM_ENABLE >> j) & 0x01);
- sclock();
- }
- for (i=0; i<3; i++) sclock();
- isp_setpin(out_MODE,LOW);
- sclock(); sclock(); /*devices at Shift-IR state*/
-
- }
- }
-
- /*************************************************************
- * *
- * DEVICE ENABLE *
- * perform the read id instruction to get devices into *
- * functional mode. *
- *************************************************************/
-
- void device_enable(short int chips)
- {
- short int i,j;
-
- /*devices come in at Shift-IR state*/
- for (i=0; i<chips+1; i++)
- for (j=0; j<5; j++) /*send the instruction into TDI*/
- {if ((i==chips)&&(j==4)) isp_setpin(out_MODE,HIGH); /*last bit*/
- isp_setpin(out_SDI,(PROGRAM_ENABLE >> j) & 0x01);
- sclock();
- }
- sclock(); /*devices at Update-IR state*/
- isp_setpin(out_MODE,LOW);
- for (i=0; i<20; i++) sclock(); /*go and loop on Run-Test/Idle for 10uS*/
- isp_setpin(out_MODE,HIGH);
- for (i=0; i<3; i++) sclock(); /*devices at Test-Logic-Reset and active*/
- }
-
- /**********************************************************************
- * *
- * READ_ISPSTREAM_HEADER *
- * Extract the header from the ispSTREAM file. *
- * Return *
- * ChainLength--------number of ispLSI devices in the *
- * given daisy chain. *
- * ErasePulse---------pulse width in mS for device *
- * bulk erase. *
- * ProgramPulse-------pulse width in mS for device *
- * row by row programming. *
- * RowLength----------the number of rows of data +UES *
- * DataSize-----------the largest size of each row of data. *
- * BEVend-------------the end of Bulk Erase verify. *
- ***********************************************************************/
- void ReadispSTREAMHeader(short int *ChainLength, short int *ErasePulse,
- short int *ProgramPulse, short int *RowLength,
- unsigned short int *DataSize,
- unsigned short int *BEVend)
- {
-
- *ChainLength = GetByte();
- *ErasePulse = GetByte() * 0x100;
- *ErasePulse += GetByte();
- *ProgramPulse = GetByte();
- *RowLength = GetByte() * 0x100;
- *RowLength += GetByte();
- *DataSize = GetByte() * 0x100;
- *DataSize += GetByte();
- *BEVend = GetByte() * 0x100;
- *BEVend += GetByte();
- /*End of the header of the ispSTREAM file.*/
-
- }
-
- /*********************************************************************
- * *
- * READ_ISPSTREAM_DATA_SIZE *
- * Extract the data size of the current row from the ispSTREAM file. *
- * Return *
- * DataSize-----------The data bit length of the current row. *
- **********************************************************************/
- void ReadispSTREAMDataSize(unsigned short int *DataSize)
- {
- short int index;
- unsigned short int temp;
- unsigned char xch;
-
- xch=0;
- temp = 0;
- for (index=0; index<16; index++)
- {--bit;
- if (bit<0)
- {
- curch = GetByte();
- bit=7;
- }
- if ((curch >> bit) & 0x01) xch |= 0x80 >> index%8;
- if (index%8==7) {temp = temp * 0x100 + xch; xch=0;}
- }
- *DataSize = temp;
- }
-
- /*****************************************************************
- * *
- * READ_ISPSTREAM_DATA *
- * Extract the data from the ispSTREAM file. *
- * SF-----------------Super FULL ispSTREAM file if true. *
- * Return *
- * DataSize-----------The number of data bits fetched. *
- * InData-------------The data stream from ispSTREAM file *
- ******************************************************************/
- void ReadispSTREAMData(unsigned short int *DataSize, unsigned char *InData,
- char SF)
- {
- unsigned short int index,size;
- short int j;
- unsigned char xch;
- short int FFcount=0;
-
- ReadispSTREAMDataSize(&size);
- if (size > 0) /*5c.001 retain the old size if the current row is NULL*/
- *DataSize = size;
- j=0;
- xch=0;
- for (index=0; index<size; index++)
- {--bit;
- if (bit<0)
- {if (FFcount<=0) /*5.1 Read a new byte if 0xFF chain exhausted*/
- { curch = GetByte();
- if ((SF)&&(curch==0xFF)) /*Super FULL ispSTREAM file support*/
- FFcount = GetByte(); /*The number of 0xFF bytes*/
- }
- else FFcount--; /*Use up the 0xFF chain first*/
- bit=7;
- }
- if ((curch >> bit) & 0x01) xch |= 0x80 >> index%8;
- if (index%8==7) {InData[j++] = xch; xch=0;}
- }
- if (size > 0) InData[j] = xch; /*save the last byte of the current row*//*5c.001*/
- }
-
- /*****************************************************************
- * *
- * ispInstruction *
- * Extract the instruction from the ispSTREAM file and clock into *
- * the devices or throw away. *
- * SF-----------------Super FULL ispSTREAM file if true. *
- * Send---------------Send data to devices if true. *
- * Return *
- * NONE *
- ******************************************************************/
- char ispInstruction(char SF, char Send)
- {
- short int index;
- short int i;
- unsigned short int size;
- short int FFcount=0;
-
- ReadispSTREAMDataSize(&size);
- for (index=0; index<size; index++)
- {--bit;
- if (bit<0)
- {if (FFcount<=0) /*5.1 Read a new byte if 0xFF chain exhausted*/
- { curch = GetByte();
- if ((SF)&&(curch==0xFF)) /*Super FULL ispSTREAM file support*/
- FFcount = GetByte(); /*The number of 0xFF bytes*/
- }
- else FFcount--; /*Use up the 0xFF chain first*/
- bit=7;
- }
- if (Send) /*send the data to the devices*/
- {isp_setpin(out_SDI,(curch >> bit) & 0x01);
- if (index==size-1) isp_setpin(out_MODE,HIGH);
- sclock(); /*clock the data into the command registers */
- }
- }
- if ((Send)&&(size > 0))
- {execute(); /*execute the instruction if sent*/
- return (1); /*signify data or instruction has actually sent*/
- }
- else return (0); /*no data or instruction send to the devices*/
- }
-
- /**********************************************************************
- * *
- * ispData *
- * Send the data stream to devices. *
- * InData-----------The data stream to be sent to devices. *
- * DataSize---------The length of the data stream. *
- ***********************************************************************/
- void ispData(unsigned char *InData, unsigned short int DataSize)
- {
- unsigned short int index;
- short int j;
- unsigned char curch;
-
- j=0;
- for (index = 0; index <DataSize; index++) {
- if (index%8==0) curch = InData[j++];
- isp_setpin(out_SDI, (((curch << index%8) & 0x80) ? 0x01 : 0x00));
- if (index==DataSize-1) isp_setpin(out_MODE,HIGH);
- sclock(); /*clock data into the data shift registers */
- }
- if (DataSize > 0) execute(); /*step to shift state*//*5c.001*/
- }
-
- /**********************************************************************
- * *
- * ispRead *
- * Read the data stream from devices and verify. *
- * DataSize---------The length of the data stream. *
- * OutData----------The data stream to be compare with those read *
- * from devices. *
- ***********************************************************************/
- char ispRead(unsigned short int DataSize, unsigned char *OutData)
- {
- unsigned short int index,error;
- unsigned char xch,cur_bit;
- short int j;
-
- j=0;
- error=0;
- xch=0;
- for (index = 0; index <DataSize; index++) {
- if (index%8==0) xch = OutData[j++];
- cur_bit=isp_SDO();
- if (cur_bit != (((xch << index%8) & 0x80) ? 0x01 : 0x00)) error++;
- if (index==DataSize-1) isp_setpin(out_MODE,HIGH);
- sclock(); /*clock data out from the data shift registers */
- }
- execute(); /*step to shift state*/
- if (error > 0) return 1; /*Flag failure occur*/
- else return (OK);
- }
-
- /*************************************************************
- * *
- * ISPSTREAM_PUMP *
- * *
- *************************************************************/
-
- short int ispstream_pump(short int operation, short int *end)
- {
- short int row;
- char SF; /*ispSTREAM file types identifier*/
- char send; /*send data to devices if true*/
- char ready; /*5c.001 ready to verify data*/
- unsigned char FileType;
- short int last_row,
- erase_pulse,
- program_pulse,
- devices_in_chain;
- unsigned short int maxi_data,
- data_length,
- be_row;
- short int rcode,condition;
- unsigned char *buf;
-
- row =0;
- bit = 0;
- /*Start reading the header of the ispSTREAM file*/
- fp = ispstream;
- FileType = GetByte();
- if (FileType == 0xF0) {SF=false;} /*Check for correct file type*/
- else if (FileType == 0x0b ) {SF=true;} /*Super FULL ispSTREAM file found*/
- else {
- return FILE_NOT_JEDEC;
- }
- ReadispSTREAMHeader(&devices_in_chain, &erase_pulse, &program_pulse,
- &last_row, &maxi_data, &be_row);
-
- rcode = OK; /*Success by default.*/
- if ((operation==verify)||(operation==verify_ues)) /*verify only*/
- {erase_pulse=0; /*void the erase instruction*/
- program_pulse=0; /*void the program instruction*/
- }
-
- /*Allocate memory to store one row of data from the ispSTREAM file.*/
- buf = buffer;
-
- /*set the initial condition of the parallel port*/
- /* All the port_pins defined on lattice.h will be controlled by
- ispstream_pump(). The rest can be initialized here either to
- HIGH or LOW and won't be altered by isptream_pump*/
-
- isp_pins = NUL; /* intialize to drive all port pins LOW*/
- isp_setpin(out_ISP, LOW);/* drive ispEN pin low to enable the
- ispJTAG controlling pins:
- TCK,TMS,TDI and TDO.*/
- move_to_id_state(); /* Go to Reset then Run-Test/Idle state*/
- isp_setpin(out_MODE,HIGH);
- sclock();
- isp_setpin(out_MODE,LOW);
- sclock(); sclock();
- state=execute_state; /* At shift-DR state*/
- isp_setpin(out_SDI,HIGH);
- ReadispSTREAMData(&data_length,buf,SF); /*fetch ID stream from ispSTREAM*/
- rcode = ispRead(data_length,buf); /*verify the ID stream*/
- if (rcode != OK)
- {
- return UNKNOWN_CHIP;
- }
- for (row=1; row<be_row; row++)
- {switch(row)
- { case 8:program_enable(devices_in_chain);/*enable programming*/
- if (erase_pulse > 0) /*erase the devices*/
- {
- state=time_state;
- ispInstruction(SF,true);
- sclock(); /*start the erase timing*/
- pulse_width(erase_pulse); /*erase pulse*/
- isp_setpin(out_MODE, HIGH);
- isp_setpin(out_SCLK,HIGH);
- pulse_width(1); /*super voltage discharge*/
- isp_setpin(out_SCLK,LOW);
- sclock();
- isp_setpin(out_MODE,LOW);
- sclock(); sclock(); /*devices in shift state*/
- state=shift_state;
- }
- else ispInstruction(SF,false); /*skipp BULK ERASE*/
- break;
- default:if (((row-9)%12==3)||((row-9)%12==8)) /*skipp BULK ERASE verify*/
- ReadispSTREAMDataSize(&data_length);
- else ispInstruction(SF,false);
- break;}
- }
- /*start processing the rows in the ispSTREAM file*/
- data_length = 0;
- for (; row <= last_row; row++) {
- *end = row; /* The row number where process ended.*/
- if (row==last_row) condition = 8; /* security programming*/
- else condition = (row-9) % 12;
- if ((operation==verify_ues)&&(row <= last_row-DATAROW)) send = false;
- else send = true;
- switch(condition){
- case 0: /*address shift*/
- case 1:ispInstruction(SF,send); /*address data*/
- break;
- case 2: /*data shift*/
- case 7:ready=ispInstruction(SF,send); /*5c.001 data shift*/
- break;
- case 3: /*shift data in/out of devices*/
- case 8:
- if ((data_length > 0)&&(ready)) /*5c.001 verify the data shifted in*/
- {state=idle_state; /*loop back to Shift-DR*/
- rcode = ispRead(data_length,buf);
- state=execute_state; /*back to shift-DR state*/
- data_length=0; /*5c.001 data verified*/
- }
- ReadispSTREAMData(&data_length,buf,SF); /*fetch data stream from ispSTREAM*/
- if (ready) ispData(buf,data_length); /*send data into devices*/
- break;
- case 4:
- case 9:if (program_pulse > 0) /*program and verify*/
- {
- state=time_state;
- if (ispInstruction(SF,true)) /*5c.001 program commands exist*/
- {sclock(); /*start program timing*/
- pulse_width(program_pulse);
- execute(); /*step to shift state*/
- }
- state=shift_state; /*5c.001 at Shift-IR*/
- }
- else ispInstruction(SF,false); /*skip programming*/
- break;
- case 5:
- case 10:state=time_state;
- if(ispInstruction(SF,send)) /*verify*/
- {sclock(); /*start verify timing*/
- pulse_width(1); /*30uS min. verify time*/
- execute(); /*step to shift state*/
- }
- state=shift_state; /*5c.001 at Shift-IR*/
- break;
- case 6:
- case 11:if (ispInstruction(SF,send))
- { rcode = ispRead(data_length,buf); /*verify the data stream*/
- data_length=0; /*don't verify again*/
- }
- break;
- default:break;
- }
- if (rcode != OK) break;
- }
-
- device_enable(devices_in_chain); /*activate the devices*/
- isp_setpin(out_ISP,HIGH); /*activate the ispLSI devices*/
- if (rcode==OK)
- return (OK);
- else return VALIDATION_ERROR;
-
- }
-
-
- /*************************************************************
- * *
- * error_handler *
- * *
- * rcode - error code *
- * *
- * *
- * This procedure return the address of the message string *
- * for the corresponding error code. *
- * *
- *************************************************************/
-
- void error_handler(short int rcode, char *message)
- {
-
- char *error_message[] = {{"PASS"},{""},{""},{"PC Hardware Problem"},{""},
- {""},{""},
- {"No Device Found/Open Download Cable/Open Daisy Chain"},
- {"Can't Find the File"},{""},{"Not Enough PC Memory"},
- {"Verification Fail"},{""},{""},
- {""},
- {"The Chip Count in the Chain and the File Do Not Match"},
- {"Unknown Device Found"},{"Wrong File Type"},{"File Error"},
- {""}};
-
- strcpy(message, error_message[-rcode]);
- }
-
- /*************************************************************
- * *
- * MAIN *
- * *
- *************************************************************/
-
- short int main(int argc, char *argv[])
- {
- short int rcode = OK,
- end = 0;
- char str[300];
-
- short int operation=prog_verify; /*3.05 Default to Program and Verify*/
-
- printf("\n Lattice Semiconductor Corp.\n");
- printf("\n ispCODE V5C.001 Copyright 1996,1997.\n");
- printf("\n ispSTREAM Driver for ispLSI 2000V Devices\n");
- printf("\n For Daisy Chain of All ISP Devices On JTAG TAP Controller\n\n");
-
- if ((argc < 1) || (argc > 2)) {
- printf("\nUsage: sturbo [operation]\n");
- printf("Example: sturbo pv\n");
- printf("\n");
- printf("operation \"pv\" = program and verify\n");
- printf(" \"v\" = Verify only\n");
- printf(" \"uv\" = Verify UES only\n");
- printf(" Default to pv if operation is not entered.\n");
- exit(1);
- }
-
- if (rcode == OK){ /*start programming and verification*/
-
- if(!strcmp(strlwr(argv[1]),"uv")){ /*3.05 What to do? uv=ues verify only*/
- operation=verify_ues; /*for verify ues only =1*/
- printf("\nStart Verify UES of ispLSI devices.......\n");}
- else if(!strcmp(strlwr(argv[1]),"v")){ /*v = verify only*/
- operation=verify;
- printf("\nStart Verify.......\n");}
- else { /*pv = program and verify: Default*/
- operation=prog_verify;
- printf("\nStart Program and Verify.......\n");
- }
- rcode = ispstream_pump(operation, &end); /*3.05 add operation switch*/
- }
- if (rcode != OK) {
- error_handler(rcode, str);
- printf("\nFailed At Row %d in Program and Verify Due To %s\n", end, str);
- printf("\n");
- printf("+-------+\n");
- printf("| FAIL! |\n");
- printf("+-------+\n");
- return (-rcode);
- } else {
- printf("\n");
- printf("+=======+\n");
- printf("| PASS! |\n");
- printf("+=======+\n");
- }
-
- return(0);
- }